﻿#include "FindFund.h"
#include "StringOperation.h"
#include"QCoding.h"
#include<iostream>
#include<regex>
#include<fstream>
#include<QFile>
#include<QFileInfo>
#include<QDir>
#include<QTextStream>
#include<QDebug>

const QString FindFund::FindName(const int code)
{   
    QString url = "http://fundgz.1234567.com.cn/js/005826.js";
    url.replace(url.indexOf("005826"),6, FindCode(code));//替换获得对应的url
    Http http;
    auto& str = http.SendRequest.GetParamStr;
    str.insert("rt","1672215544639");
    http.SendRequest.setReferer ( "http://fund.eastmoney.com");
    
    http.Get(url.toLocal8Bit().data());//发送请求
    http.recv();//接收
    string Text = http.getText();
    //cout << Text << endl;;

    //开始正则匹配
    smatch mat;//用作匹配的对象
    regex pattren("\"name\":\"\(.*?\)\"");
    string::const_iterator start = Text.begin();//起始位置
    string::const_iterator end = Text.end();//结束位置

    while (regex_search(start, end, mat, pattren)) {
        string msg(mat[1].first, mat[1].second);
       // cout << "找到名字：" << msg << endl;
        return msg.c_str();
        start = mat[0].second;//改变起始位置
    }

    return QString();
}

const QString FindFund::FindCode(const int num)
{
    char temp[10]{ 0 };
    sprintf(temp, "%06d", num);//转成6位基金代码
    return QString(temp);
}

const int FindFund::FindCode(const string& code)
{
    return atoi(code.c_str());
}

const QString FindFund::GetFilePath(const QString& PathName)
{
    QString path;
    int nSel = PathName.indexOf("/");
    if (nSel >= 0)
    {
        path = PathName.left(nSel);
    }
    else
    {
        path = PathName;
    }
    return path;
}

const QString FindFund::GetFileName(const QString& PathName, const bool suffix)
{
    QFileInfo info(PathName);
    if(suffix)
        return info.fileName();
    else
        return info.baseName();
}
const int FindFund::FindHistoryOnePage(const int code, const int Index, const int Size)
{
   /* if (m_History == nullptr)
        m_History = new map<int, map<QString, HistoricalDetails>>;*/
    Http http;
    QString Referer = "http://fundf10.eastmoney.com/jjjz_005827.html";
    Referer.replace(Referer.indexOf("005827"), 6, FindCode(code));//替换获得对应的url
    http.SendRequest.setReferer(Referer.toLocal8Bit().data());
    auto& str = http.SendRequest.GetParamStr;
    str.insert("callback", "find");
    str.insert("fundCode", FindCode(code).toLocal8Bit().data());
    str.insert("pageIndex", to_string(Index));
    str.insert("pageSize", to_string(Size));
    str.insert("startDate", "");
    str.insert("endDate", "");
    str.insert("_", "");
    //cout << "\r\n连接开始\r\n";
    http.Get("http://api.fund.eastmoney.com/f10/lsjz");
    http.recv();
    string Text = http.getText();
    //开始正则匹配
    smatch mat;//用作匹配的对象
    regex pattren("\\{\"FSRQ\":\"\(.*?\)\",\"DWJZ\":\"\(.*?\)\",\"LJJZ\":\"\(.*?\)\",.*?,\"JZZZL\":\"\(.*?\)\",\"SGZT\":\"\(.*?\)\",\"SHZT\":\"\(.*?\)\",.*?\\}");
    string::const_iterator start = Text.begin();//起始位置
    string::const_iterator end = Text.end();//结束位置
    int n = 0;
    while (regex_search(start, end, mat, pattren)) {
        string date(mat[1].first, mat[1].second);
        string AverVal(mat[2].first, mat[2].second);
        string CumuVal(mat[3].first, mat[3].second);
        string probab(mat[4].first, mat[4].second);
        std::string applyPurchase(mat[5].first, mat[5].second);
        std::string redeem(mat[6].first, mat[6].second);
        (m_History)[code][date.c_str()] = HistoricalDetails(AverVal, CumuVal, probab, applyPurchase, redeem);
        n++;
        start = mat[0].second;//改变起始位置
    }


    //cout << Text;
    return n;
}

const int FindFund::FindHistoryOne(const int code, const int Size)
{
    int size = 0, r = 0,i=1;
    do
    {
        r=FindHistoryOnePage(code,i,Size);
        i++;
        size += r;
        //cout << r << endl;;
    } while (r);
    return size;
}

const int FindFund::WriteHistoryOne(const int code,const QString& Path)
{
    if ((m_History)[code].empty())
        return 0;
    int n = 0;
    QDir dir(Path);
    if (!dir.exists())
    {
        dir.mkpath("a");  //创建一个目录(文件夹)
        dir.rmdir("a");
    }
    QString PathName ;
    if (Path.isEmpty())//没有指定目录
    {
        PathName = FindCode(code) + ".csv";
    }
    else
    {
        PathName = Path + "/" + FindCode(code) + ".csv";
    }

    fstream  file(PathName.toLocal8Bit().data(), ios::out | ios::trunc| ios::binary);
    if (!file.is_open())
    {
        qWarning() << "文件打开失败";
        return 0;
    }
    //QDataStream Text(&file);
    file << FundName(code).toLocal8Bit().data()<<"\r\n";
    file <<QString("净值日期,单位净值,累计净值,日增长率,申购状态,赎回状态").toLocal8Bit().data();
    for (auto& data : (m_History)[code])
    {
        auto& v = data.second;
        file << "\r\n" << data.first.toLocal8Bit().data() << "," << v.AverVal<< "," << v.CumuVal <<","<<v.probab<<","<<v.applyPurchase.toLocal8Bit().data() <<","<<v.redeem.toLocal8Bit().data();
        n++;
    }
    //Text.flush();
    return n;
}

const int FindFund::WriteHistoryAll(const QString& path, const int Index, const int Size)
{
    
    int n = 0; 
    auto it = m_FundForm.begin();
    for (size_t i = 0; i < Index-1; i++)
    {
        it++;
        n++;
    }
    for (; it!= m_FundForm.end(); it++)
    {
        FindHistoryOne(it->first,Size);
        int num=WriteHistoryOne(it->first, path);
        qInfo() << n << ":(" << num << "条)";
        n++;
        qInfo() << FundName(it->first) <<"--"<<"写入到本地完成";
        m_History.clear();
        /*delete m_History;
        m_History=nullptr;*/
        //Sleep(1000);
    }
    return n;
}

const int FindFund::WriteHistoryAll(const QString& path, const QString& code, const int Size)
{
    auto itTar = find_if(m_FundForm.begin(), m_FundForm.end(), [=](pair<const int, FundInfo>& data) {
        return data.second.code == code.toLocal8Bit().data();
        });
    int n = 1;
    auto it = m_FundForm.begin();
    while (it!= itTar&&it!= m_FundForm.end())
    {
        n++;
        it++;
    }
    //cout << n<<":"<<FindName(itTar->first);
    return WriteHistoryAll(path, n + 1,Size);
}

const int FindFund::ReadHistoryOne(const QString& PathName)
{
    QFile file(PathName);
    if (!file.open(QIODevice::OpenModeFlag::ReadOnly))
    {
        qWarning() << "打开文件失败";
        return 0;
    }
    QString code = GetFileName(PathName,false);
    int Code = code.toInt();
    QString Text;
    int n = 0;
    while (!file.atEnd())
    {
#ifdef _WIN32
        Text = QCoding::GbkToUtf8(file.readLine().trimmed().data()).c_str();
#else
        Text = file.readLine().trimmed();
#endif // _WIN32
        n++;
        if (n > 2)
        {
            auto v = StringOperation::strtok(Text,",");
            (m_History)[Code][v[0]] = HistoricalDetails(v[1], v[2], v[3], v[4], v[5]);
        }
        else if (n ==2&&Text != "净值日期,单位净值,累计净值,日增长率,申购状态,赎回状态")
        {
            return 0;
        }
    }
    file.close();
    if (n > 0)
        n--;
    return n;
}

void FindFund::whileFundHistory(const int code)
{
    /*if (m_History == nullptr)
        return;*/
    qInfo() << FundName(code);
    const char* format = "%-15s%-12.4lf%-12.4lf%12.2lf%% %-20s%-10s\r\n";
    std::cout << QString::asprintf("%-15s%-12s%-12s%12s  %-20s%-10s\r\n", "净值日期", "单位净值", "累计净值", "日增长率", "申购状态", "赎回状态").toLocal8Bit().data();
    for (auto&data: (m_History)[code])
    {
        auto& v = data.second;
        //qInfo()<<QString().asprintf(format, data.first.toUtf8().data(), v.AverVal, v.CumuVal, v.probab, v.applyPurchase.toLocal8Bit().data(), v.redeem.toLocal8Bit().data());
       printf(format, data.first.toLocal8Bit().data(), v.AverVal, v.CumuVal, v.probab, v.applyPurchase.toLocal8Bit().data(), v.redeem.toLocal8Bit().data());
    }
}

map<int, map<QString, HistoricalDetails>>& FindFund::FundHistory()
{
    return m_History;
}

const int FindFund::FindFundName()
{
    QString url = "http://fund.eastmoney.com/js/fundcode_search.js";
    Http http;
    http.Get(url.toLocal8Bit().data());//发送请求
    //qInfo()<<url;
    http.recv();//接收

    string Text = http.getText();
    //cout<<Text;
    //开始正则匹配
    smatch mat;//用作匹配的对象
    regex pattren("\\[\"\(\\d*?\)\",\".*?\",\"\(.*?\)\",\"\(.*?\)\",\".*?\"\\]");
    string::const_iterator start = Text.begin();//起始位置
    string::const_iterator end = Text.end();//结束位置
    int n = 0;
    while (regex_search(start, end, mat, pattren)) {
        string code(mat[1].first, mat[1].second);
        string name(mat[2].first, mat[2].second);
        string type(mat[3].first, mat[3].second);
        m_FundForm[FindCode(code)] = FundInfo(code,name,type);
        n++;
        /* cout << "基金代码：" << QString(mat[1].first, mat[1].second) <<"--";
         cout << "基金名字：" << QString(mat[2].first, mat[2].second) <<"--";
         cout <<  QString(mat[3].first, mat[3].second) << endl;*/
        start = mat[0].second;//改变起始位置
    }
    
    
    //cout << Text.substr(0,1000) << endl;

    return n;
}

const int FindFund::WriteFundName(const QString& PathName)
{
    int n = 0;
    QString path = GetFilePath(PathName);
    //qInfo() << path;
    QDir dir(path);
    if (!dir.exists())
    {
        dir.mkpath("a");  //创建一个目录(文件夹)
        dir.rmdir("a");
    }
    //QFile file(PathName);
    fstream file(PathName.toLocal8Bit().data(), ios::out | ios::binary | ios::trunc);//二进制写
    //if (!file.open(QIODevice::OpenModeFlag::WriteOnly))
    if (!file.is_open())
    {
        qWarning() << "文件打开失败";
        return 0;
    }
    //QTextStream Text(&file);
    file << QString("基金名字,基金代码,基金类型").toLocal8Bit().data();
    for (auto& data: m_FundForm)
    {
        file <<"\r\n"<< data.second.name.toLocal8Bit().data() << "," << data.second.code.toLocal8Bit().data() << "," << data.second.type.toLocal8Bit().data();
        n++;
    }
    //Text.flush();
    return n;
}

const int FindFund::ReadFundName(const QString& PathName)
{
    QFile file(PathName);
    if (!file.open(QIODevice::OpenModeFlag::ReadOnly))
    {
        qWarning() << "打开文件失败";
        return 0;
    }
    QString Text;
    int n = 0;
    while (!file.atEnd())
    {
#ifdef _WIN32
        Text = QCoding::GbkToUtf8(file.readLine().trimmed().data()).c_str();
#else
        Text = file.readLine().trimmed();
#endif // _WIN32
        n++;
        if (n >1)
        {
            auto v = StringOperation::strtok(Text, ",");
            m_FundForm[v[1].toInt()] = FundInfo(v[1], v[0], v[2]);
        }
        else if(Text!="基金名字,基金代码,基金类型")
        {
            return 0;
        }
    }
   /* qInfo() << Text.c_str() ;*/
    file.close();
    if (n > 0)
        n--;
    return n;
}

void FindFund::whileFundName()
{
    for (auto &data: m_FundForm)
    {
        qInfo() << data.second.name << "(" << data.second.code << ")" << data.second.type;
    }
}

const QString FindFund::FundName(const int code)
{
    
    auto& data = m_FundForm[code];
    if (data.name.isEmpty())
    {
        data.name = FindName(code);
        data.code = FindCode(code);
    }
    QString str=QString("%1(%2)%3").arg(data.name).arg(data.code).arg(data.type);
    //str= data.name + "(" + data.code + ")" + data.type;
    return str;
}

map<int, FundInfo>& FindFund::FundForm()
{
    return m_FundForm;
}

void FindFund::claerFundForm()
{
    m_FundForm.clear();
}

